/*
* Copyright (c) 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.api.services.samples.adexchangebuyer.creativessubmit;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.IOUtils;
import com.google.api.services.adexchangebuyer.AdExchangeBuyer;
import com.google.api.services.adexchangebuyer.AdExchangeBuyerRequest;
import com.google.api.services.adexchangebuyer.AdExchangeBuyerScopes;
import com.google.api.services.adexchangebuyer.model.Creative;
import com.google.api.services.adexchangebuyer.model.PretargetingConfig;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.GeneralSecurityException;
/**
* Wraps calls to the AdExchange Buyer API
*/
public class BuyerServiceHelper {
/**
* Be sure to specify the name of your application. If the application name is {@code null} or
* blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
*/
protected static final String APPLICATION_NAME = "";
/**
* Email account for the Service Account. Get this and the P12 Key File at
* https://console.developers.google.com
*/
private static final String SERVICE_ACCOUNT_EMAIL =
"INSERT_SERVICE_ACCOUNT_EMAIL";
/** Full path to P12 Key file - include file name */
private static final java.io.File P12_FILE =
new java.io.File("INSERT_PATH_TO_P12_FILE");
/**
* Fields in the Creatives object that must not be sent on insert/update/patch requests
*/
protected static final String[] CREATIVE_READONLY_FIELDS = {"advertiserId",
"corrections",
"disapprovalReasons",
"filteringReasons",
"productCategories",
"sensitiveCategories",
"status"};
/**
* Fields in the PretargetingConfig object that must not be sent on insert/update/patch requests
*/
protected static final String[] PRETARGETING_CONFIG_READONLY_FIELDS = {"billingId", "configId"};
/**
* Handle to the API service
*/
private AdExchangeBuyer service;
/**
* handler user input and output
*/
private BuyerServiceInputUtils inputHelper;
/**
* @return the API service
*/
protected AdExchangeBuyer getService() {
return service;
}
public BuyerServiceHelper(BuyerServiceInputUtils inputHelper) throws GeneralSecurityException,
IOException {
super();
this.inputHelper = inputHelper;
this.service = getNewService();
}
/**
* Retrieves the authenticated user's list of accounts.
*/
public void accountsList() {
try {
run(getService().accounts().list());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Retrieves a list of the authenticated user's active creatives.
*/
public void creativesList() {
try {
String filter = inputHelper.getCreativeListFilter();
run(getService().creatives().list().setOpenAuctionStatusFilter(filter)
.setDealsStatusFilter(filter));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Gets the status for a single creative.
*/
public void creativesGet() {
try {
long accountId = inputHelper.getAccountId();
String creativeId = inputHelper.getCreativeId();
String filePath = inputHelper.getCreativeFilePath();
run(getService().creatives().get((int) accountId, creativeId), true, filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Inserts a new creative into Google's creative verification pipeline.
*/
public void creativesInsert() {
try {
String filePath = inputHelper.getCreativeFilePath();
Creative creative = readObjectFromFile(filePath, Creative.class);
BuyerServiceHelper.cleanCreative(creative);
run(getService().creatives().insert(creative));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Retrieves a list of the pretargeting configurations for the passed accountId.
*/
public void pretargetingConfigList() {
try {
long accountId = inputHelper.getAccountId();
run(getService().pretargetingConfig().list(accountId));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Gets a specific pretargeting configuration.
*/
public void pretargetingConfigGet() {
try {
long accountId = inputHelper.getAccountId();
long configId = inputHelper.getPretargetingConfigId();
String filePath = inputHelper.getPretargetingFilePath();
run(getService().pretargetingConfig().get(accountId, configId), true, filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Inserts a new pretargeting configuration.
*/
public void pretargetingConfigInsert() {
try {
long accountId = inputHelper.getAccountId();
String filePath = inputHelper.getPretargetingFilePath();
PretargetingConfig config = readObjectFromFile(filePath, PretargetingConfig.class);
BuyerServiceHelper.cleanPretargetingConfig(config);
run(getService().pretargetingConfig().insert(accountId, config));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Updates an existing pretargeting config.
* Note: The contents of the json file will replace any existing data; not be merged with it.
*/
public void pretargetingConfigUpdate() {
try {
long accountId = inputHelper.getAccountId();
long configId = inputHelper.getPretargetingConfigId();
String filePath = inputHelper.getPretargetingFilePath();
PretargetingConfig config = readObjectFromFile(filePath, PretargetingConfig.class);
BuyerServiceHelper.cleanPretargetingConfig(config);
run(getService().pretargetingConfig().update(accountId, configId, config));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Runs a request against the service
* @param request is the service method to run
* @return json results from request
* @throws IOException
*/
protected String run(AdExchangeBuyerRequest<?> request) throws IOException {
return run(request, true, "");
}
/**
* Runs a request against the service
* @param request is the service method to run
* @param display displays returned results when true
* @param filePath returned results are saved to this path
* @return json results from request
* @throws IOException
*/
protected String run(AdExchangeBuyerRequest<?> request, boolean display, String filePath)
throws IOException {
HttpResponse response = request.executeUnparsed();
String json = getResultAsString(response);
if (display) {
System.out.println(json);
}
if (!filePath.isEmpty()) {
Files.write(Paths.get(filePath), json.getBytes(), StandardOpenOption.CREATE);
}
return json;
}
/**
* reads results from the response object and converts them to a String
* @param response you want to read content from
* @return the response content as a String
* @throws IOException
*/
protected static String getResultAsString(HttpResponse response) throws IOException {
InputStream content = response.getContent();
if (content == null) {
return "";
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(content, out);
String json = out.toString(response.getContentCharset().name());
return json;
}
/**
* Reads serialized data from a file to recreate an object
* @param filePath the file to read
* @param dataClass the object type
* @return a instantiated object of type dataClass
* @throws IOException
*/
protected <T> T readObjectFromFile(String filePath, Class<T> dataClass) throws IOException {
String json = new String(Files.readAllBytes(Paths.get(filePath)));
StringReader reader = new StringReader(json);
return service.getObjectParser().parseAndClose(reader, dataClass);
}
/**
* Sets fields from CREATIVE_READONLY_FIELDS as null
* @param creative is the Creative to clean
*/
protected static void cleanCreative(Creative creative) {
for (String field : CREATIVE_READONLY_FIELDS) {
creative.set(field, null);
}
}
/**
* Sets fields from PRETARGETING_CONFIG_READONLY_FIELDS as null
* @param config is the PretargetingConfig to clean
*/
protected static void cleanPretargetingConfig(PretargetingConfig config) {
for (String field : PRETARGETING_CONFIG_READONLY_FIELDS) {
config.set(field, null);
}
}
/**
* Creates a new API service
* @return the new, authenticated and authorized service
* @throws GeneralSecurityException
* @throws IOException
*/
protected static AdExchangeBuyer getNewService() throws GeneralSecurityException, IOException {
/** Global instance of the HTTP transport. */
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
/** Global instance of the JSON factory. */
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
Credential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(AdExchangeBuyerScopes.all())
.setServiceAccountPrivateKeyFromP12File(P12_FILE)
.build();
return new AdExchangeBuyer.Builder(httpTransport, jsonFactory, credential).setApplicationName(
APPLICATION_NAME).build();
}
}